/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedbean.ProcurementBP;

import java.util.ArrayList;
import java.util.Collection;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import merlion.common.entity.DocFile;
import merlion.common.session.stateless.FileManagerSessionLocal;
import merlion.frm.bpm.entity.SupplierInvoice;
import merlion.frm.bpm.session.ProcurementBPSessionBeanLocal;
import merlion.scm.rmpm.entity.RawMaterialItemLine;
import merlion.scm.rmpm.entity.RawMaterialSalesOrder;
import merlion.scm.rmpm.entity.RawMaterialSupplyInformation;
import merlion.scm.rmpm.entity.Supplier;
import merlion.scm.rmpm.session.RawMaterialPurchaseSessionBeanLocal;
import org.primefaces.context.RequestContext;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

/**
 *
 * @author Kenn
 */
@ManagedBean
@ViewScoped
public class SupplierInvoiceManagerBean {
    
    @EJB
    private ProcurementBPSessionBeanLocal pbpSessionBean;
    @EJB
    private RawMaterialPurchaseSessionBeanLocal rmpSessionBean;
    @EJB
    private FileManagerSessionLocal fileManager;
    private SupplierInvoice invoice;
    private Collection<SupplierInvoice> invoices;
    private RawMaterialItemLine rmil;
    private RawMaterialItemLine rmilBackup;
    private String statusMsg;

    //--------------------------------------------------------------------------
    //                              Constructor
    //--------------------------------------------------------------------------
    public SupplierInvoiceManagerBean() {
        statusMsg = (String) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("statusMsg");
        invoice = (SupplierInvoice) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("invoice");
        
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("statusMsg");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("invoice");
        
        if(invoice == null){
            invoice = new SupplierInvoice();
            invoice.setSupplier(new Supplier());
            invoice.setSupplierPaymentRecord(null);
            rmil = new RawMaterialItemLine();
        }
        
    }
    
    //--------------------------------------------------------------------------
    //                  Supplier Inovice Manager Bean Methods
    //--------------------------------------------------------------------------
    
    public Collection<RawMaterialSalesOrder> getAllSalesOrderWOInvoice(){
        return pbpSessionBean.getAllSalesOrderWOInvoice();
    }
    
    public void selectSalesOrder(ActionEvent event) {
        invoice.setSupplier(invoice.getRmso().getSupplier());
    }

    public Collection<RawMaterialSupplyInformation> getSupplierRawMaterial() {
        return invoice.getSupplier().getRawMaterialsSupplied();
    }

    public void addItemLine(ActionEvent event) {

        // Validate
        RequestContext context = RequestContext.getCurrentInstance();
        boolean valid = true;
        if (rmil.getRawMaterialSupplyInformation() == null || rmil.getRawMaterialSupplyInformation().getRawMaterial().getName().equals("")) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Raw Material is required", ""));
            valid = false;
        }
        if (rmil.getQty() == 0D) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Quantity cannot be zero", ""));
            valid = false;
        }

        ArrayList<RawMaterialItemLine> list = new ArrayList<RawMaterialItemLine>(invoice.getItemLines());
        list.remove(rmil);
        boolean materialExist = false;
        for (RawMaterialItemLine r : list) {
            if (rmil.getRawMaterialSupplyInformation().getRawMaterial().equals(r.getRawMaterialSupplyInformation().getRawMaterial())) {
                materialExist = true;
            }
        }
        if (materialExist) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Raw material is already in order items", ""));
            valid = false;
        }
        context.addCallbackParam("valid", valid);
        if (!valid) {
            return;
        }

        rmil = rmpSessionBean.calculateLine(rmil);
        invoice.getItemLines().add(rmil);

        rmil = new RawMaterialItemLine();
    }

    public void cancelAddItemLine(ActionEvent event) {
        rmil = new RawMaterialItemLine();
    }

    public void editItemLine(ActionEvent event) {
        rmil = (RawMaterialItemLine) event.getComponent().getAttributes().get("selected");
        rmilBackup = rmil.clone();
    }

    public void updateItemLine(ActionEvent event) {

        RequestContext context = RequestContext.getCurrentInstance();
        boolean valid = true;
        if (rmil.getRawMaterialSupplyInformation() == null || rmil.getRawMaterialSupplyInformation().getRawMaterial().getName().equals("")) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Raw Material is required", ""));
            valid = false;
        }
        if (rmil.getQty() == 0D) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Quantity cannot be zero", ""));
            valid = false;
        }
        if (rmil.getQty() % rmil.getRawMaterialSupplyInformation().getRawMaterial().getLotSize() != 0L) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Quantity must be ordered in lot size", ""));
            valid = false;
        }
        context.addCallbackParam("valid", valid);
        if (!valid) {
            return;
        }

        rmil = rmpSessionBean.calculateLine(rmil);
        rmil = new RawMaterialItemLine();
    }

    public void cancelEditItemLine(ActionEvent event) {
        rmil.setQty(rmilBackup.getQty());
        rmil.setRawMaterialSupplyInformation(rmilBackup.getRawMaterialSupplyInformation());
        rmil.setSubtotalSGD(rmilBackup.getSubtotalSGD());
        rmil.setSubtotalUSD(rmilBackup.getSubtotalUSD());
    }

    public void removeItemLine(ActionEvent event) {
        rmil = (RawMaterialItemLine) event.getComponent().getAttributes().get("selected");
    }

    public void confirmRemoveItemLine(ActionEvent event) {
        invoice.getItemLines().remove(rmil);
        rmil = new RawMaterialItemLine();
    }

    public void cancelRemoveItemLine(ActionEvent event) {
        rmil = new RawMaterialItemLine();
    }
    
    public void handleFileUploadSupplierInvoice(FileUploadEvent event) {
        
        UploadedFile file = event.getFile();
        //application code
        DocFile myDoc = new DocFile(file.getFileName(), file.getContentType(), file.getContents());
        invoice = fileManager.uploadFileIntoSupplierInvoice(myDoc, invoice);
        if (invoice != null) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_INFO, "Supplier Invoice uploaded successfully", ""));
        } else {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Supplier Invoice upload failed", ""));
        }
    }
    
    public String saveInvoice(){
        
        boolean valid = true;
        if (invoice.getSupplierInvoiceNo() == null || invoice.getSupplierInvoiceNo().equals("")) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invoice Id cannot be empty", ""));
            valid = false;
        }
        if (invoice.getCurrency() == null) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Currency is required", ""));
            valid = false;
        }
        if (invoice.getUploadedImage() == null) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Supplier Invoice File must be uploaded", ""));
            valid = false;
        }
        if (invoice.getInvoiceAmount() == null || invoice.getInvoiceAmount() <= 0) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Total amount is invalid", ""));
            valid = false;
        }
        if (!valid) {
            return null;
        }

        // Perform purchase order matching
        if (!pbpSessionBean.matchSupplierInvoiceItems(invoice)) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Order Items in sales order is different. Please check with supplier on the correct order items and quantities", ""));
            return null;
        }
        if (!pbpSessionBean.matchSupplierInvoiceCurrency(invoice)) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Currency in sales order is different. Please check with supplier on currency", ""));
            return null;
        }
        if (!pbpSessionBean.matchSupplierInvoiceTotal(invoice)) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Total amount in sales order is different. Please check with supplier on correct total amount to be paid", ""));
            return null;
        }
        
        invoice = pbpSessionBean.saveSupplierInvoice(invoice);
        if(invoice != null){
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("statusMsg", "Supplier Invoice saved successfully.");
        } else {
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("statusMsg", "Supplier Invoice cannot be saved. Pleaase try again.");
        }
        return "storeInvoiceStatus?faces-redirect=true";
    }
    
    public String viewSupplierInvoice(){
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("invoice", invoice);
        return "viewInvoiceDisplay?faces-redirect=true";
    }
    
    public String editSupplierInvoice(){
        return null;
    }
    
    //--------------------------------------------------------------------------
    //                           Getter and Setter
    //--------------------------------------------------------------------------

    public SupplierInvoice getInvoice() {
        return invoice;
    }

    public void setInvoice(SupplierInvoice invoice) {
        this.invoice = invoice;
    }

    public String getStatusMsg() {
        return statusMsg;
    }

    public void setStatusMsg(String statusMsg) {
        this.statusMsg = statusMsg;
    }

    public Collection<SupplierInvoice> getInvoices() {
        return pbpSessionBean.getAllSupplierInvoice();    }

    public void setInvoices(Collection<SupplierInvoice> invoices) {
        this.invoices = invoices;
    }

    public RawMaterialItemLine getRmil() {
        return rmil;
    }

    public void setRmil(RawMaterialItemLine rmil) {
        this.rmil = rmil;
    }
    
}
